package com.gmail.viktor.yuryev.ui;

import com.gmail.viktor.yuryev.model.MyRemoteServers;
import com.gmail.viktor.yuryev.model.ServerDetails;
import com.intellij.openapi.options.BaseConfigurable;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.ui.Splitter;
import com.intellij.ui.*;
import com.intellij.ui.components.JBList;
import com.intellij.util.Consumer;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by Viktor Yuryev on 4/9/2014.
 */

public class ServerListConfigurationForm extends BaseConfigurable {
    private final ServerConfigurationForm serverListConfigurationForm;
    private final Consumer<ServerDetails> myChangeListener;
    private JList serversList;
    private final List<ServerDetails> myRepositories = new ArrayList<ServerDetails>();

    private JPanel rootComponent;
    private JPanel serversPanel;
    private Splitter mySplitter;
    private JPanel myRepositoryEditor;
    private JPanel myEmptyPanel;
    private JComponent serverEditorPanel;
    private JLabel myServersLabel;


    private class AddServerAction implements AnActionButtonRunnable {
        @Override
        public void run(AnActionButton anActionButton) {
            ServerDetails element = new ServerDetails();
            element.setHost("undefined");
            ((CollectionListModel) serversList.getModel()).add(element);
            myRepositories.add(element);
            ((CardLayout) myRepositoryEditor.getLayout()).show(myRepositoryEditor, ServerConfigurationForm.class.getName());
        }
    }

    private class RemoveServerAction implements AnActionButtonRunnable {
        @Override
        public void run(AnActionButton anActionButton) {
            ServerDetails selectedRepository = getSelectedRepository();
            if (selectedRepository != null) {
                CollectionListModel model1 = (CollectionListModel) serversList.getModel();
                model1.remove(selectedRepository);
                myRepositories.remove(selectedRepository);

                if (model1.getSize() > 0) {
                    serversList.setSelectedValue(model1.getElementAt(0), true);
                } else {
                    serversList.removeAll();
                    serversList.repaint();
                }
            }
        }
    }

    private class SelectServerAction implements ListSelectionListener {
        public void valueChanged(ListSelectionEvent e) {
            ServerDetails repository = getSelectedRepository();
            if (repository != null) {
                serverListConfigurationForm.setData(repository);
                ((CardLayout) myRepositoryEditor.getLayout()).show(myRepositoryEditor, ServerConfigurationForm.class.getName());
                serverEditorPanel.repaint();
                mySplitter.doLayout();
                mySplitter.repaint();
            }
        }
    }


    public ServerListConfigurationForm() {
        serversList = new JBList();
        MyRemoteServers instance = MyRemoteServers.getInstance();
        for (ServerDetails serverDetails : instance.getServerList()) {
            myRepositories.add(serverDetails);
        }
        serversList.setModel(new CollectionListModel(myRepositories));


        ToolbarDecorator toolbarDecorator = ToolbarDecorator.createDecorator(serversList).disableUpDownActions();

        serversList.setCellRenderer(new ListCellRendererWrapper<ServerDetails>() {
            @Override
            public void customize(JList jList, ServerDetails serverDetails, int i, boolean b, boolean b2) {
                setText(serverDetails.getHost() + serverDetails.getPort());
            }
        });
        //Actions:
        toolbarDecorator.setRemoveAction(new RemoveServerAction());
        toolbarDecorator.setAddAction(new AddServerAction());
        serversList.getSelectionModel().addListSelectionListener(new SelectServerAction());
        serversPanel.add(toolbarDecorator.createPanel(), BorderLayout.CENTER);


        myChangeListener = new Consumer<ServerDetails>() {
            public void consume(ServerDetails repository) {
                ((CollectionListModel) serversList.getModel()).contentsChanged(repository);
            }
        };
        serverListConfigurationForm = new ServerConfigurationForm(myChangeListener);


        //todo it smells bad
        serverEditorPanel = serverListConfigurationForm.createComponent();
        myRepositoryEditor.add(serverEditorPanel, ServerConfigurationForm.class.getName());

    }

    @Override
    public JComponent getPreferredFocusedComponent() {
        return serversList;
    }

    @Nullable
    private ServerDetails getSelectedRepository() {
        return (ServerDetails) serversList.getSelectedValue();
    }



    public JComponent getRootComponent() {
        return rootComponent;
    }

    @Override
    public boolean isModified() {
        List<ServerDetails> serverList123 = MyRemoteServers.getInstance().getServerList();
        return !myRepositories.equals(serverList123);
    }

    @Nls
    @Override
    public String getDisplayName() {
        return "Servers";
    }

    @Nullable
    @Override
    public String getHelpTopic() {
        return null;
    }

    @Nullable
    @Override
    public JComponent createComponent() {
        return rootComponent;
    }

    @Override
    public void apply() throws ConfigurationException {
        List<ServerDetails> newRepositories = ContainerUtil.map(myRepositories, new Function<ServerDetails, ServerDetails>() {
            public ServerDetails fun(ServerDetails taskRepository) {
                return taskRepository.clone();
            }
        });
        MyRemoteServers.getInstance().setServers(newRepositories);
    }

    @Override
    public void reset() {
      //  myRepositoryEditor.removeAll();
      //  myRepositoryEditor.add(myEmptyPanel, EMPTY_PANEL);
//    ((CardLayout)myRepositoryEditor.getLayout()).show(myRepositoryEditor, );
        myRepositories.clear();

        CollectionListModel listModel = new CollectionListModel(new ArrayList());
        for (ServerDetails repository : MyRemoteServers.getInstance().getServerList()) {
            ServerDetails clone = repository.clone();
            myRepositories.add(clone);
            listModel.add(clone);
        }
        serversList.setModel(listModel);
        if (!myRepositories.isEmpty()) {
            serversList.setSelectedValue(myRepositories.get(0), true);
        }
    }


    @Override
    public void disposeUIResources() {

    }
}
